/*!
\copyright  Copyright (c) 2023 Qualcomm Technologies International, Ltd.\n
            All Rights Reserved.\n
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\brief      Private Header file for USB Audio class 2.0 driver
*/

#ifndef USB_AUDIO_CLASS_20_H_
#define USB_AUDIO_CLASS_20_H_


#include "usb_audio_class.h"

/** A.14 Audio Class-Specific Request Codes
Table A-14: Audio Class-Specific Request Codes */
typedef enum
{
    UAC2_REQUEST_CODE_UNDEFINED = 0x00,
    UAC2_CUR = 0x01,
    UAC2_RANGE = 0x02,
    UAC2_MEM = 0x03
} uac2_request_code_t;

/* Audio Device Class Request Types */
#define SET       0x00
#define GET       0x80

/* Helpers */
#define REQ_CS(req)         ((req).wValue >> 8)
#define REQ_CN(req)         ((req).wValue & 0xFF)
#define REQ_CODE(req)       ((req).bRequest & 0x07)
#define REQ_UNIT(req)       ((req).wIndex >> 8)
#define REQ_INTERFACE(req)  ((req).wIndex & 0xFF)
#define REQ_IS_GET(req)     ((req).bmRequestType & GET)


#define CONVERT_FROM_3BYTES_LE(x) (((x)[0]) | ((uint32)((x)[1]) << 8)  | ((uint32)((x)[2]) << 16))

#define CONVERT_TO_3BYTES_LE(x,y) ((x)[0] = (uint8)((y) & 0xFF), \
                                     (x)[1] = (uint8)((y) >> 8),  \
                                     (x)[2] = (uint8)((y) >> 16))

/*!  See uac_enumerate_streaming() */
#define INTF_DESC_INDEX_FROM_ALT_SETTINGS(alt_setting)     ((alt_setting)? (alt_setting)- 1:(alt_setting))

/*! Structure to hold USB Audio Control Class-Specific Header descriptor
    This structure is taken from USB Device Class Definition for Audio Devices
    This is only used for accessing descriptor values not for allocating memory */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType;
    uint8 bDescriptorSubType;
    uint8 bcdADC_lo;
    uint8 bcdADC_hi;
    uint8 bCategory;
    uint8 wTotalLength_lo;
    uint8 wTotalLength_hi;
    uint8 bmControls;
} uac2_cs_header_desc_t;

/*! Structure to hold USB Audio format descriptor
    This structure is taken from UUSB Device Class Definition for Audio Data Format
    This is only used for accessing descriptor values not for allocating memory */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType;
    uint8 bDescriptorSubtype;
    uint8 bFormatType;
    uint8 bSubslotSize;
    uint8 bBitResolution;
} uac2_format_descriptor_t;

/*! Structure to hold USB Audio format descriptor
    This structure is taken from UUSB Device Class Definition for Audio Data Format
    This is only used for accessing descriptor values not for allocating memory */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType;
    uint8 bDescriptorSubtype;
    uint8 bTerminalLink;
    uint8 bmControls;
    uint8 bFormatType;
    uint8 bmFormats[4];
    uint8 bNrChannels;
    uint8 bmChannelConfig[4];
    uint8 iChannelNames;
} uac2_as_general_descriptor_t;

/*! USB Audio Class 1.0: 4.3.2.5 Feature Unit Descriptor */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType; /* UAC_CS_DESC_INTERFACE */
    uint8 bDescriptorSubtype; /* UAC_AC_DESC_FEATURE_UNIT */
    uint8 bUnitID;
    uint8 bSourceID;
    uint8 bmaControls1[4];
    uint8 bmaControls2[4];
    uint8 bmaControls3[4];
    uint8 iFeature;
} uac_feature_unit_descriptor_t;

/** Clock source descriptor */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType;
    uint8 bDescriptorSubtype;
    uint8 bClockID;
    uint8 bmAttributes;
    uint8 bmControls;
    uint8 bAssocTerminal;
    uint8 iClockSource;
} uac2_clock_source_desc_t;

/*! USB Audio Class 2.0, 4.7.2.4, Input Terminal Descriptor */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType; /* UAC_CS_DESC_INTERFACE */
    uint8 bDescriptorSubtype; /* UAC_AC_DESC_INPUT_TERMINAL */
    uint8 bTerminalID;
    uint16 wTerminalType;
    uint8 bAssocTerminal;
    uint8 bCSourceID;
    uint8 bNrChannels;
    uint8 bmChannelConfig[4];
    uint8 iChannelNames;
    uint16 bmControls;
    uint8 iTerminal;
} uac_input_terminal_descriptor_t;

/*! USB Audio Class 2.0, 4.7.2.5, Output Terminal Descriptor */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType; /* UAC_CS_DESC_INTERFACE */
    uint8 bDescriptorSubtype; /* UAC_AC_DESC_OUTPUT_TERMINAL */
    uint8 bTerminalID;
    uint16 wTerminalType;
    uint8 bAssocTerminal;
    uint8 bSourceID;
    uint8 bCSourceID;
    uint16 bmControls;
    uint8 iTerminal;
} uac_output_terminal_descriptor_t;

/*! Generic Class Descriptor */
typedef struct
{
    uint8 bLength;
    uint8 bDescriptorType;
    uint8 bDescriptorSubtype;
} uac_generic_descriptor_t;

#define USB_AUDIO_PACKET_RATE_HZ                    1000

/* Round up _value to the nearest _multiple. */
#define ROUNDUP(_value, _multiple) (((_value) + (_multiple) - 1) / (_multiple))

#define UAC_MAX_PACKET_SIZE(sample_rate_hz, channels, sample_size)         \
    (ROUNDUP(sample_rate_hz, USB_AUDIO_PACKET_RATE_HZ) *   \
    (sample_size) * (channels))

/*! \brief Interface to get function pointers for class driver.

    \return Return function table for usb_audio_class_10 driver interface .
*/
usb_fn_tbl_uac_if *UsbAudioClass20_GetFnTbl(void);


#endif /* USB_AUDIO_CLASS_20_H_ */
